var Address_Cover = "location...";
var Name_Cover = "trail name...";
var isShowInfoWindow = false;
function MyMapToolsKit(options) {
    this._options = {
        mapCanvas: $(options.mapCanvas),
        mapOptions: options.mapOptions,
        mapSearchBoxOptions: options.mapSearchBoxOptions,
        embed:options.embed
    };
    var mapCanvas = this._options.mapCanvas;
    var mapCanvasPosition = mapCanvas.position();
    this._map = null;
    this._map = new google.maps.Map(mapCanvas.get(0), this._options.mapOptions);
    this._geocoder = new google.maps.Geocoder();
    this._addressMarker = null;
    var searchBoxOptions = this._options.mapSearchBoxOptions;
    this._mapSearchBox = $(searchBoxOptions.clone).clone().appendTo(mapCanvas).addClass(searchBoxOptions.className);

    var mapToolkit = this;
    var seachType = this.searchType();
    this.searchType(seachType);

    var searchInputValue = seachType == "address" ? Address_Cover : Name_Cover;
    this._mapSearchBox.find(searchBoxOptions.searchInput)
            .attr("value", searchInputValue)
            .addClass("search_input_cover")
            .keydown(function (e) {
                var keyCode = e.keyCode;
                if (keyCode == 13) {
                    mapToolkit.search($(this).attr('value'));
                    return false;
                }
            })
            .focusin(function () {
                if ($(this).hasClass("search_input_cover")) {
                    $(this).attr("value", "");
                    $(this).removeClass("search_input_cover");
                }
            })
            .focusout(function () {
                var searchInputValue = mapToolkit.searchType() == "address" ? Address_Cover : Name_Cover;
                if ($(this).attr("value").trim() == "") {
                    $(this).attr("value", searchInputValue);
                    $(this).addClass("search_input_cover");
                }
            });
    var searchbox = this._mapSearchBox;
    var searchBoxPosition = this._options.mapSearchBoxOptions.searchBoxPosition;
    this._mapSearchBox.css({ left: searchBoxPosition[0], top: searchBoxPosition[1] });
    this._mapSearchBox.find(searchBoxOptions.searchCancel).click(function () {
        searchbox.find(searchBoxOptions.searchInput).attr('value', '');
        mapToolkit.search('');
    });
    
    this._mapSearchBox.find('.search_option').click(function () {
        var position = $(this).position();
        $(this).parent().find('.search_type_options').show()
				.css('left', position.left + 'px')
				.css('top', position.top + 'px');
    });

    this._mapSearchBox.find(".search_type_options li").click(function () {
        var st = $(this).attr("searchtype");
        var searchInputValue = st == "address" ? Address_Cover : Name_Cover;
        mapToolkit.searchType(st);
        mapToolkit._mapSearchBox.find(searchBoxOptions.searchInput).attr("value", searchInputValue)
                .addClass("search_input_cover"); ;
        $(this).parent().hide();
        mapToolkit._map.setCenter(mapToolkit._options.mapOptions.center);
        mapToolkit._map.setZoom(mapToolkit._options.mapOptions.zoom);
    });
    $(document).click(function (e) {
        if (e.target != mapToolkit._mapSearchBox.find('.search_option').get(0)) {
            mapToolkit._mapSearchBox.find(".search_type_options").hide();
        }
        //isShowInfoWindow=false;
    }); 
}
MyMapToolsKit.prototype.searchType = function (value) {
    if (value && typeof value == 'string') {
        jQuery.cookie("searchtype", value);
        this._mapSearchBox.find(".search_type_options li")
            	.each(function (i, n) {
            	    if ($(n).attr("searchtype") == value) {
            	        $(n).addClass("selected");
            	    }
            	    else {
            	        $(n).removeClass("selected");
            	    }
            	});
    }
    else {
        var searchType = jQuery.cookie("searchtype");
        if (searchType == null || searchType == "") {
            searchType = "address";
            this.searchType(searchType);
        }
        return searchType;
    }
};
MyMapToolsKit.prototype.initialize = function (data) {
    this._data = data;
    this._markers = [];
    var styles = $(this._data).find("Style");
    var placemarks = $(this._data).find("Placemark");
    this.renderKml(placemarks, styles);
    var toolskit = this;
    google.maps.event.addListener(this._map, "bounds_changed", function () {
        if(!isShowInfoWindow){
        	toolskit.filter();
        }
    });
};
MyMapToolsKit.prototype.filter = function () {
    var allStyles = $(this._data).find("Style");
    var allPlacemarks = $(this._data).find("Placemark");
    var styles = [];
    var placemarks = [];
    var bounds = this._map.getBounds();
    allPlacemarks.each(function (i, n) {
        var coordinfos = findCoordinfos(n);
        var position = new google.maps.LatLng(coordinfos[1], coordinfos[0]);
        if (bounds.contains(position)) {
            placemarks.push(allPlacemarks[i]);
            styles.push(allStyles[i]);
        }
    });
    this.renderKml($(placemarks), $(styles));
};
MyMapToolsKit.prototype.search = function (params) {
    var map = this._map;
    var toolskit = this;
    if (toolskit._addressMarker) {
        toolskit._addressMarker.setMap(null);
    }
    var allStyles = $(this._data).find("Style");
    var allPlacemarks = $(this._data).find("Placemark");
    var styles = [];
    var placemarks = [];
    if (params.length > 0) {
        var searchType = jQuery.cookie("searchtype");
        if (searchType == null || searchType == "") {
            searchType = "name";
            jQuery.cookie("searchtype", searchType);
        }
        if (searchType == "address") {
            this._geocoder.geocode({ 'address': params },
                        	function (results, status) {
                        	    if (status == google.maps.GeocoderStatus.OK) {
                        	        map.setCenter(results[0].geometry.location);
                        	        map.fitBounds(results[0].geometry.viewport);
                        	        toolskit._addressMarker = new google.maps.Marker({
                        	            map: map,
                        	            position: results[0].geometry.location
                        	        }); 
                        	    } else {
                        	        alert("Can't find the address: " + params + " as the reason of " + status);
                        	    }
                        	});
        }
        else {         
            allPlacemarks.each(function (i, n) {
                var name = findChildNodeText(n, "name").toLowerCase();
                if (name.indexOf(params.toLowerCase()) >= 0) {
                    placemarks.push(allPlacemarks[i]);
                    styles.push(allStyles[i]);
                }
            });
        }
        this.renderKml($(placemarks), $(styles));
    } else {
        this.renderKml(allPlacemarks, allStyles);
    }
};
MyMapToolsKit.prototype.renderKml = function (placemarks, styles) {
    this.clearMarkers();
    var map = this._map;
    var markers = this._markers;
    var toolsKit = this;
    placemarks.each(function (i, n) {
        var iconHref = findHref(styles.get(i)); // $(styles.get(i)).find("IconStyle>Icon>href");
        //var coords = find(n,'Point>coordinates');// $(n).find("Point>coordinates");
        var coordinfos = findCoordinfos(n); // text(coords).split(",");
        var position = new google.maps.LatLng(coordinfos[1], coordinfos[0]);
        var description = findDescription(n); //$(n).find("description").text();
        var marker = new google.maps.Marker({ icon: text(iconHref), map: map, position: position });
        google.maps.event.addListener(marker, 'click', function () {
        	isShowInfoWindow = true;
        	if (toolsKit._infowindow) {
                toolsKit._infowindow.close();
            }
            var informationDiv = $('.to_information_box').clone();
            informationDiv.find(".msinfotitle").html(findChildNodeText(n, "name"));
            informationDiv.find(".msiwcontentholder").html(description);
            informationDiv.find(".directions").click(function () { getDirections(); });
            informationDiv.find(".searchnearby").click(function () { searchNearby(); });

            if(toolsKit._options.embed!='0'){
            	$(informationDiv).find('.msiwcontentholder a').attr('target','_top');
            }
            
            var content = informationDiv.html();

            toolsKit.showInforWindow(toolsKit, map, marker, content);
        });
        markers.push(marker);
    });
};
MyMapToolsKit.prototype.showInforWindow = function (toolsKit, map, marker, content) {
    var infowindow = new google.maps.InfoWindow({
        content: content
    });
    infowindow.open(map, marker);
    google.maps.event.addListener(infowindow, "closeclick", function () {
    	isShowInfoWindow = false;
    });
    toolsKit._infowindow = infowindow;
};
MyMapToolsKit.prototype.showInforWindow0 = function (toolsKit, map, marker, content) {
    var infoWindow = new ExtInfoWindow(
                     'infowindow',
                     {
                         showMode: 'center',
                         content: content,
                         close: '.map2_propwind_close'
                     }
                     );
    map.setExtInfoWindow(infoWindow);
    toolsKit._infowindow = infoWindow;
};
MyMapToolsKit.prototype.clearMarkers = function () {
    $(this._markers).each(function (i, n) {
        n.setMap(null);
    });
    this._markers.splice(0, jQuery(this._markers).size());
};
function loadXML(xmlText) {
    var xmlDoc;
    if (window.ActiveXObject) {
        xmlDoc = new ActiveXObject('Microsoft.XMLDOM');
        xmlDoc.async = false;
        xmlDoc.loadXML(xmlText);
    }
    else if (DOMParser) {
        parser = new DOMParser();
        xmlDoc = parser.parseFromString(xmlText, "text/xml");
    }
    else {
        return null;
    }
    return xmlDoc;
}
function findHref(styleNode) {
    if (window.ActiveXObject) {
        return styleNode.childNodes[0].childNodes[0].childNodes[0];
    }
    else {
        return $(styleNode).find("IconStyle>Icon>href");
    }
}
function findCoordinfos(placemark) {
    if (window.ActiveXObject) {
        var value = "";
        $(placemark.childNodes).each(function (i, n) {
            if (n.tagName == "Point") {
                value = n.childNodes[0].text;
                return;
            }
        });
        return value.split(',');
    }
    else {
        return $(placemark).find("Point>coordinates").text().split(',');
    }
}
function findDescription(placemark) {
    return findChildNodeText(placemark, 'description');
}
function findChildNodeText(placemark, childNodeName) {
    if (window.ActiveXObject) {
        var value = "";
        $(placemark.childNodes).each(function (i, n) {
            if (n.tagName.toLowerCase() == childNodeName.toLowerCase()) {
                value = n.text;
                return;
            }
        });
        return value;
    }
    else {
        return $(placemark).find(childNodeName).text();
    }
}
function text(xmlNode) {
    if (window.ActiveXObject) {
        return xmlNode.text;
    }
    else {
        return $(xmlNode).text();
    }
}
function getDirections() {
}
function searchNearby() {
}